﻿#include "tcp_socket.h"

tcp_socket::tcp_socket(QObject *parent)
{
    this->setParent(parent);
    connect(this,SIGNAL(readyRead()),this,SLOT(receive()));
    connect(this,SIGNAL(disconnected()),this,SLOT(connect_server()),Qt::QueuedConnection);
    connect(&clock,SIGNAL(timeout()),this,SLOT(isdisconnect()));
    Lastconnecttime=QDateTime::currentDateTime();
    clock.start(10000);
    this->ip=Common::ip;
    this->port=Common::port;
}

tcp_socket::~tcp_socket()
{
    qDebug()<<"删除SOCKET";
    disconnect(this,SIGNAL(readyRead()),this,SLOT(receive()));
    disconnect(this,SIGNAL(disconnected()),this,SLOT(connect_server()));
    disconnectFromHost();
    close();
}


void tcp_socket::receive()
{
    receive_data+=read(bytesAvailable());
    analyse_data();
}


void tcp_socket::analyse_data()
{

    while(receive_data.size()>(sizeof(qint32)+sizeof(qint64)))
    {
        bool isCompress=false;
        qint64 data_size;
        qint32 feature;
        QByteArray data;
        QDataStream dts(&receive_data,QIODevice::ReadWrite);
        dts>>feature>>data_size;
        if(feature==this->feature)
        {
            if(data_size<=receive_data.size())
            {
                dts.device()->seek(sizeof(qint32)+sizeof(qint64));
                dts>>isCompress;
                dts>>data;

                if (isCompress)
                {
                    data=qUncompress(data);
                }

                receive_data.remove(0,data_size);
                process_data(data);

            }
            else
            {
                break;
            }
        }
        else
        {
            qDebug()<<"特征值错误，断开socket";
            disconnectFromHost();
            close();
            break;
        }
    }
}



void tcp_socket::process_data(QByteArray data)
{

    QString id,type,information;
    QStringList result=json_analyse(data);
    qDebug()<<result;
    if(result.size()>=3)
    {
        id=result[0];
        type=result[1];
        information=result[2];
        if(type=="心跳包")
        {
            return;
        }
        this->Lastconnecttime=QDateTime::currentDateTime();
        emit reply_data(result);
       emit socket_isconnect(true);
    }
}

void tcp_socket::ConnectToServer()
{
    connect_server();
}

void tcp_socket::connect_server()
{
    bool isconnect=false;

        abort(); //取消已有的连接
        connectToHost(ip,port);
        if (!waitForConnected(500))
        {
            qDebug()<<"连接服务器失败!请检查ip,端口";
            emit socket_isconnect(false);
        }
        else
        {
            qDebug()<<"连接服务器成功";
            emit socket_isconnect(true);

        }
        if(state()==QAbstractSocket::ConnectedState)
        {
            isconnect=true;
        }

}


void tcp_socket::send_data(QString id, QString type, QString data)
{

    QByteArray socket_packdata=packdata(id,type,data);
    bool isCompress=false;
    //qDebug()<<socket_packdata.size()<<qCompress(socket_packdata).size();
    if(socket_packdata.size()>qCompress(socket_packdata).size())
    {
        isCompress=true;
        socket_packdata=qCompress(socket_packdata);
    }
    QByteArray senddata;
    QDataStream dts(&senddata,QIODevice::WriteOnly);
    dts<<(qint32)0<<(qint64)0<<(bool)isCompress<<socket_packdata;
    dts.device()->seek(0);
    dts<<feature;
    dts.device()->seek(sizeof(qint32));
    dts<<(qint64)senddata.size();
    write(senddata);
    flush();



}


void tcp_socket::isdisconnect()
{
    if(Lastconnecttime.secsTo(QDateTime::currentDateTime())>10)
    {
        send_data(id,"心跳包","");
        this->Lastconnecttime=QDateTime::currentDateTime();
    }
    if(Lastconnecttime.secsTo(QDateTime::currentDateTime())>30||state()==QTcpSocket::UnconnectedState)
    {
        connectToHost(ip,port);
        if (!waitForConnected(2000))
        {
            qDebug()<<"连接服务器失败!请检查ip,端口";
        }
        else
        {
            qDebug()<<"连接服务器成功";
        }
    }
}


QByteArray tcp_socket::packdata(QString id, QString type, QString data)
{
    this->id=id;
    QJsonObject json;
    json.insert("id", id);
    json.insert("type", type);
    json.insert("data", data);
    QJsonDocument document;
    document.setObject(json);
    QByteArray byte_array = document.toJson(QJsonDocument::Compact);
    return byte_array;
}

void tcp_socket::setpassword(QString password)
{
    this->password=password;
}

QStringList tcp_socket::json_analyse(QByteArray data)
{
    QString id,type,message;
    QStringList result;
    QJsonParseError json_error;
    QJsonDocument parse_doucment = QJsonDocument::fromJson(data, &json_error);
    if(json_error.error == QJsonParseError::NoError)
    {
        if(parse_doucment.isObject())
        {
            QJsonObject obj = parse_doucment.object();
            if(obj.contains("id"))
            {
                QJsonValue id_value = obj.take("id");
                if(id_value.isString())
                {
                    id = id_value.toString();
                }
            }
            if(obj.contains("type"))
            {
                QJsonValue type_value = obj.take("type");
                if(type_value.isString())
                {
                    type = type_value.toString();
                }
            }
            if(obj.contains("data"))
            {
                QJsonValue data_value = obj.take("data");
                if(data_value.isString())
                {
                    message = data_value.toString();
                }
            }
            result<<id<<type<<message;
           // qDebug()<<"json解析结果为:"<<result;

        }
        else
        {
            qDebug()<<"json不是对象"<<json_error.error;
        }

    }
    else
    {
        qDebug()<<"json格式错误！";
    }
    return result;
}
